home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1990
/
03
/
pat&flen.lst
< prev
next >
Wrap
File List
|
1990-02-13
|
9KB
|
397 lines
MANAGING MULTIPLE DATA SEGMENT UNDER MICROSOFT WINDOWS: PART II
by Tim Paterson and Steve Flenniken
[LISTING ONE]
[LISTING ONE]
/* segments.c */
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "segments.h"
#include "segtable.h"
int szAppNameLength = 8;
char *szAppName = "Segments";
char *szClocks = "Too many clocks or timers!";
char *szOutOfMemory = "Not enough memory.";
#define MAX_VARIABLE_PSEGS (MAXPSEGS - MINPSEGS - 1)
typedef struct data {
PSEG pseg;
SEG lastseg;
SEG oldseg;
short changed;
} DATA, FAR * DATAP;
PSEG psegdata;
#define FARDATAP ( (DATAP)FARPTR(0, *psegdata) )
short xchar;
short ychar;
BOOL random_action = TRUE;
int action_count = 0;
HWND hWindow;
PSEG allocate(LONG size, char *string);
BOOL reallocate(PSEG pseg, LONG size, char *string);
LONG FAR PASCAL SegmentsWndProc(HWND, unsigned, WORD, LONG);
int FAR PASCAL timer_routine(HWND hwnd, unsigned message, short id, LONG time);
IFP strcpyifp(IFP string1, IFP string2);
int strlenifp(IFP string);
int FAR PASCAL timer_routine(HWND hwnd, unsigned message, short id, LONG time)
{
/* Randomly allocate/free a segment in the Segment Table or
monitor the Segment Table for movement. Update the line in the window
that changes.
*/
int i;
LONG size;
char buffer[40];
RECT rect;
int random_switch;
message;
id;
time;
if (random_action)
{
if (++action_count < 10)
return(0);
action_count = 0;
i = rand() % MAX_VARIABLE_PSEGS;
size = (LONG)rand(); /* 0 <= size <= 32767 */
sprintf(buffer, " %d bytes", (short)size);
random_switch = rand();
if (FARDATAP[i].pseg)
{
if (random_switch > 2*32767/4)
{
if (FARDATAP[i].lastseg == 0) /* if data is free */
FARDATAP[i].changed = -1; /* reset the count */
buffer[0] = 'R';
reallocate(FARDATAP[i].pseg, size, buffer);
}
else if (random_switch > 1*32767/4)
{
SegmentFree(FARDATAP[i].pseg);
FARDATAP[i].pseg = 0;
}
else if (*FARDATAP[i].pseg)
DataFree(FARDATAP[i].pseg);
}
else
{
buffer[0] = 'A';
FARDATAP[i].pseg = allocate(size, buffer);
FARDATAP[i].changed = -1;
}
SetRect(&rect, 9*xchar, (i+2)*ychar, 46*xchar, (i+3)*ychar);
InvalidateRect(hwnd, &rect, TRUE);
}
for (i = 0; i < MAX_VARIABLE_PSEGS; i++)
{
if (FARDATAP[i].lastseg != *FARDATAP[i].pseg)
{
FARDATAP[i].oldseg = FARDATAP[i].lastseg;
FARDATAP[i].lastseg = *FARDATAP[i].pseg;
FARDATAP[i].changed++;
SetRect(&rect, 9*xchar, (i+2)*ychar, 46*xchar, (i+3)*ychar);
InvalidateRect(hwnd, &rect, TRUE);
}
}
return(0);
}
void SegmentsPaint(HDC hDC)
{
char buffer[100];
short len;
int i;
TextOut(hDC, 9*xchar, ychar, "pseg seg oldseg moved", 23);
for (i = 0; i < MAX_VARIABLE_PSEGS; i++)
{
len = sprintf(buffer, "data[%d] %.4X %.4X", i, FARDATAP[i].pseg, *FARDATAP[i].pseg);
TextOut(hDC, xchar, (i+2)*ychar, buffer, len);
if (FARDATAP[i].pseg)
{
if (*FARDATAP[i].pseg == 0)
TextOut(hDC, 31*xchar, (i+2)*ychar, "Data Free", 9);
else
{
len = sprintf(buffer, "%.4X %.2X", FARDATAP[i].oldseg, FARDATAP[i].changed);
TextOut(hDC, 21*xchar, (i+2)*ychar, buffer, len);
strcpyifp(MAKEIFP(buffer, &segDgroup),MAKEIFP(0, FARDATAP[i].pseg));
len = strlenifp(MAKEIFP(buffer, &segDgroup));
TextOut(hDC, 31*xchar, (i+2)*ychar, buffer, len);
}
}
else
TextOut(hDC, 31*xchar, (i+2)*ychar, "Free", 4);
}
}
IFP strcpyifp(IFP string1, IFP string2)
{
char FAR *str1;
char FAR *str2;
str1 = IFP2PTR(string1);
str2 = IFP2PTR(string2);
while (1)
{
*str1++ = *str2;
if (*str2 == 0)
break;
str2++;
}
return(string1);
}
int strlenifp(IFP string)
{
char FAR *str;
int len;
str = IFP2PTR(string);
for (len = 0; str[len] != 0; len++)
;
return(len);
}
BOOL SegmentsInit(HANDLE hInstance)
{
WNDCLASS SegmentsClass;
SegmentsClass.hCursor = LoadCursor(NULL, IDC_ARROW);
SegmentsClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(SEGTABLEICON));
SegmentsClass.lpszMenuName = "segmentsmenu";
SegmentsClass.lpszClassName = szAppName;
SegmentsClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
SegmentsClass.hInstance = hInstance;
SegmentsClass.style = CS_HREDRAW | CS_VREDRAW;
SegmentsClass.lpfnWndProc = SegmentsWndProc;
if (!RegisterClass((LPWNDCLASS)&SegmentsClass))
return FALSE;
return TRUE;
}
PSEG allocate(LONG size, char *string)
{
/*
Allocate 'size' bytes from the global heap. Copy a null terminated
'string' into the allocated memory.
*/
PSEG pseg;
char FAR *farptr;
int i;
if (!(pseg = SegmentAlloc(size)))
return NULL;
farptr = FARPTR(0, *pseg);
for (i = 0; string[i] && i < (int)size-1; i++)
farptr[i] = string[i];
farptr[i] = 0;
return pseg;
}
BOOL reallocate(PSEG pseg, LONG size, char *string)
{
/*
Allocate 'size' bytes from the global heap. Copy a null terminated string
'string' into the allocated memory.
*/
char FAR *farptr;
int i;
if (!(SegmentRealloc(pseg, size)))
return FALSE;
farptr = FARPTR(0, *pseg);
for (i = 0; string[i] && i < (int)size-1; i++)
farptr[i] = string[i];
farptr[i] = 0;
return TRUE;
}
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
{
MSG msg;
HWND hWnd;
int i;
TEXTMETRIC tm;
HDC hdc;
FARPROC lpprocTimer;
DATAP datap;
lpszCmdLine;
if (!hPrevInstance)
if (!SegmentsInit(hInstance))
return FALSE;
SegmentInit();
if (!(psegdata = SegmentAlloc((DWORD)sizeof(DATA)*MAX_VARIABLE_PSEGS)))
{
MessageBox(hWnd, szOutOfMemory, szAppName, MB_OK);
return FALSE;
}
datap = FARPTR(0, *psegdata);
for (i = 0; i < MAX_VARIABLE_PSEGS; i++)
{
datap[i].lastseg = 0;
datap[i].pseg = 0;
}
hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
GetTextMetrics(hdc, &tm);
xchar = tm.tmAveCharWidth;
ychar = tm.tmHeight;
DeleteDC(hdc);
hWindow = hWnd = CreateWindow(szAppName, szAppName, WS_TILEDWINDOW, 0, 0,46*xchar, 14*ychar, NULL, NULL, hInstance, NULL);
lpprocTimer = MakeProcInstance(timer_routine, hInstance);
while (!SetTimer(hWnd, 1, 100, lpprocTimer))
{
if (IDCANCEL == MessageBox(hWnd, szClocks, szAppName, MB_ICONEXCLAMATION | MB_RETRYCANCEL))
return FALSE;
}
ShowWindow(hWnd, cmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LONG FAR PASCAL SegmentsWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
{
PAINTSTRUCT ps;
switch (message)
{
case WM_COMMAND:
switch (wParam)
{
case MENU_START:
random_action = TRUE;
break;
case MENU_STOP:
random_action = FALSE;
break;
default:
break;
}
break;
case WM_DESTROY:
KillTimer(hWnd, 1);
PostQuitMessage(0);
break;
case WM_PAINT:
BeginPaint(hWnd, &ps);
SegmentsPaint(ps.hdc);
EndPaint(hWnd, &ps);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return(0L);
}
[LISTING TWO]
/* segments.h */
#define SEGTABLEICON 1
#define MENU_START 50
#define MENU_STOP 51
[LISTING THREE]
# segments.mak
cp=cl -d -DDEBUG -c -W2 -DLINT_ARGS -AM -Gswc -Os -Zdpi
.c.obj:
$(cp) $*.c >$*.err
type $*.err
segtable.obj: segtable.c segtable.h
segments.obj: segments.c segments.h segtable.h
segments.res: segments.rc segments.ico segments.h
rc -r segments.rc
segments.exe: segments.obj segments.res segments.def segtable.obj
link4 /linenumbers/co segments segtable,/align:16,/map,mlibw/noe,segments.def
mapsym segments
rc segments.res
[LISTING FOUR]
/* segments.rc */
#include "segments.h"
SEGTABLEICON ICON segments.ico
segmentsmenu MENU
BEGIN
MENUITEM "Start!", MENU_START
MENUITEM "Stop!", MENU_STOP
END
[LISTING FIVE]
; segments.def
NAME Segments
DESCRIPTION 'Segments'
STUB 'WINSTUB.EXE'
CODE MOVEABLE
DATA MOVEABLE MULTIPLE
HEAPSIZE 10000
STACKSIZE 4096
EXPORTS
SegmentsWndProc @1
timer_routine @2